#include "MutiThreadServer.h"

HANDLE hMutex;

void Thread1(void* buf)
{
    printf("CurrentThreadId::%d\n", GetCurrentThreadId());
    sockInfo* sock=(sockInfo*)buf;

    char clientIP[16]="\0";
    inet_ntop(AF_INET, &sock->addr.sin_addr.s_addr, clientIP, 16); 
    printf("Client ip:%s,Port:%d...\n",clientIP , ntohs(sock->addr.sin_port));

    char recvBuf[1024]={};
    char sendError[127]="The message is error!!!";
    while (true)
    {
      WaitForSingleObject(hMutex, INFINITE);
      //调用recv函数接收客户端发送的信息
      int nLen = recv(sock->fd, recvBuf, 128, 0);
      if (nLen <= 0) {
        printf("Client closed!!!(from: %d)\n", ntohs(sock->addr.sin_port));
        break;
      }
      printf("Recv successful...(from: %d)\n", ntohs(sock->addr.sin_port));
      
      //根据接收到的信息，进行处理，并调用send返回对应的处理信息
      DataPackage* dp= (DataPackage*)recvBuf;
      if(dp->dealMode==1){
        StrToUpper(dp->str,strlen(dp->str));
        send(sock->fd, (const char*)dp->str, strlen(dp->str), 0);
      }
      else if(dp->dealMode==2){
        StrToLower(dp->str,strlen(dp->str));
        send(sock->fd, (const char*)dp->str, strlen(dp->str), 0);
      }
      else{
        send(sock->fd, (const char*)sendError, strlen(sendError), 0);
      }

      ReleaseMutex(hMutex);

      Sleep(100);
    }

  closesocket(sock->fd);
}


void MultiThreadServerAPI()
{
    //加载Windows环境
  WORD ver = MAKEWORD(2, 2);
  WSADATA dat;
  WSAStartup(ver, &dat);

  sockInfo sockInfos[128];
  HANDLE hThread[128];
  
  //创建socket
  SOCKET Server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  sockaddr_in Server_sin = {};
  Server_sin.sin_family = AF_INET;
  Server_sin.sin_port = htons(SERVER_PORT);
  //Server_sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //INADDR_ANY为默认地址
  //将十进制SERVER_IP转化为二进制保存至Server_sin.sin_addr中
  inet_pton(AF_INET, SERVER_IP, &Server_sin.sin_addr);

  socklen_t optval = 1;
  setsockopt(Server_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval));

  //调用bind，将服务端本地地址到socket上
  if (SOCKET_ERROR == bind(Server_sock, (sockaddr*)&Server_sin, sizeof(Server_sin)))
  {
    printf("Bind failed!!!\n");
  }
  else {
    printf("Bind successful...\n");
  }

  //调用listen函数进行监听
  if (SOCKET_ERROR == listen(Server_sock, 128))
  {
    printf("Listen failed!!!\n");
  }
  else {
    printf("Listen successful...\n");
  }
  for(int i=0;i<128;i++)
  {
    sockInfos[i].fd=-1;
  }

  //调用accept接收客户端连接申请，并将客户端信息保存至Client_sin中
  int ii = 0;
  while(1)
  {
    sockaddr_in Client_sin = {};
    char IPdotdec[20];
    int nAddrLen = sizeof(sockaddr_in);

    SOCKET Client_sock = INVALID_SOCKET;
    Client_sock = accept(Server_sock, (sockaddr*)&Client_sin, &nAddrLen);
    if (Client_sock == INVALID_SOCKET)
    {
      printf("Accept Client_sin failed!!!\n");
      break;
    }
    else
    {
      printf("Accept clirntAddr successful... Sock = %d,IP = %s \n", (int)Client_sock, inet_ntop(AF_INET, &Client_sin.sin_addr, IPdotdec, 16));
    }

    sockInfo* sock; 
    int i = 0;
    for (; i < 128; i++) {
      if (sockInfos[i].fd == -1) {
        sock = &sockInfos[i];
        break;
      }
      if (i == 127) {
        Sleep(1);
        i--;
      }
    }
    memcpy(&sock->fd,&Client_sock,sizeof(Client_sock));
    memcpy(&sock->addr, &Client_sin, sizeof(Client_sin));
    hThread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread1, (LPVOID)&sockInfos[i], 0, NULL);
    ii++;
  }

  WaitForMultipleObjects(ii, hThread, TRUE, INFINITE);

  closesocket(Server_sock);
  //
  WSACleanup();
  printf("Sever closed ...");
  getchar();
}